/*
 * Copyright 2015 泛泛o0之辈
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.jfast.framework.base.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class StringUtils {
	
	public static final String EMPTY = "";

	public static final int INDEX_NOT_FOUND = -1;

	public static final String[] EMPTY_STRING_ARRAY = new String[0];
	
	private static ScriptEngineManager sem = new ScriptEngineManager();
	
	private static ScriptEngine se = sem.getEngineByName("js");

	public static String null2String(String str) {
		return null == str ? "" : str;
	}

	public static String getString(String str, String dft) {
		return null == str ? dft : str;
	}

	public static int getInt(String str, int dft) {
		return null == str ? dft : Integer.parseInt(str);
	}

	public static boolean isEmpty(String str) {
		return str == null || str.length() == 0;
	}

	public static boolean isBlank(String str) {
		int strLen;
		if (str == null || (strLen = str.length()) == 0) {
			return true;
		}
		for (int i = 0; i < strLen; i++) {
			if ((Character.isWhitespace(str.charAt(i)) == false)) {
				return false;
			}
		}
		return true;
	}

	public static boolean isNotBlank(String str) {
		return !StringUtils.isBlank(str);
	}

	public static boolean isNotEmpty(String str) {
		return !StringUtils.isEmpty(str);
	}

	/**
	 * 首字母变大写
	 */
	public static String firstCharToUpperCase(String str) {
		char firstChar = str.charAt(0);
		if (firstChar >= 'a' && firstChar <= 'z') {
			char[] arr = str.toCharArray();
			arr[0] -= ('a' - 'A');
			return new String(arr);
		}
		return str;
	}

	public static boolean contains(String str, char searchChar) {
		if (isEmpty(str)) {
			return false;
		}
		return str.indexOf(searchChar) >= 0;
	}

	public static boolean contains(String str, String searchStr) {
		if (str == null || searchStr == null) {
			return false;
		}
		return str.indexOf(searchStr) >= 0;
	}

	public static String join(Object[] array, String separator) {
		if (array == null) {
			return null;
		}
		return join(array, separator, 0, array.length);
	}

	public static String join(Object[] array, String separator, int startIndex,
			int endIndex) {
		if (array == null) {
			return null;
		}
		if (separator == null) {
			separator = EMPTY;
		}
		int bufSize = (endIndex - startIndex);
		if (bufSize <= 0) {
			return EMPTY;
		}

		bufSize *= ((array[startIndex] == null ? 16 : array[startIndex]
				.toString().length()) + separator.length());

		StringBuilder buf = new StringBuilder(bufSize);

		for (int i = startIndex; i < endIndex; i++) {
			if (i > startIndex) {
				buf.append(separator);
			}
			if (array[i] != null) {
				buf.append(array[i]);
			}
		}
		return buf.toString();
	}

	public static String substringBetween(String str, String open, String close) {
		if (str == null || open == null || close == null) {
			return null;
		}
		int start = str.indexOf(open);
		if (start != INDEX_NOT_FOUND) {
			int end = str.indexOf(close, start + open.length());
			if (end != INDEX_NOT_FOUND) {
				return str.substring(start + open.length(), end);
			}
		}
		return null;
	}

	public static String[] substringsBetween(String str, String open,
			String close) {
		if (str == null || isEmpty(open) || isEmpty(close)) {
			return null;
		}
		int strLen = str.length();
		if (strLen == 0) {
			return EMPTY_STRING_ARRAY;
		}
		int closeLen = close.length();
		int openLen = open.length();
		List<String> list = new ArrayList<String>();
		int pos = 0;
		while (pos < (strLen - closeLen)) {
			int start = str.indexOf(open, pos);
			if (start < 0) {
				break;
			}
			start += openLen;
			int end = str.indexOf(close, start);
			if (end < 0) {
				break;
			}
			list.add(str.substring(start, end));
			pos = end + closeLen;
		}
		if (list.isEmpty()) {
			return null;
		}
		return (String[]) list.toArray(new String[list.size()]);
	}

	public static String replace(String text, String searchString,
			String replacement) {
		return replace(text, searchString, replacement, -1);
	}

	public static String replace(String text, String searchString,
			String replacement, int max) {
		if (isEmpty(text) || isEmpty(searchString) || replacement == null
				|| max == 0) {
			return text;
		}
		int start = 0;
		int end = text.indexOf(searchString, start);
		if (end == INDEX_NOT_FOUND) {
			return text;
		}
		int replLength = searchString.length();
		int increase = replacement.length() - replLength;
		increase = (increase < 0 ? 0 : increase);
		increase *= (max < 0 ? 16 : (max > 64 ? 64 : max));
		StringBuilder buf = new StringBuilder(text.length() + increase);
		while (end != INDEX_NOT_FOUND) {
			buf.append(text.substring(start, end)).append(replacement);
			start = end + replLength;
			if (--max == 0) {
				break;
			}
			end = text.indexOf(searchString, start);
		}
		buf.append(text.substring(start));
		return buf.toString();
	}
	
	public static boolean hasLength(CharSequence str) {
		return null != str && str.length() > 0;
	}
	
	public static boolean hasLength(String text) {
		return hasLength((CharSequence)text);
	}
	
	public static boolean hasText(CharSequence str) {
		if (!hasLength(str)) {
			return false;
		}
		int strLen = str.length();
		for (int i = 0; i < strLen; i++) {
			if (!Character.isWhitespace(str.charAt(i))) {
				return true;
			}
		}
		return false;
	}
	
	public static boolean hasText(String text) {
		return hasText((CharSequence)text);
	}

	public static String firstCharToLowerCase(String str) {
		char firstChar = str.charAt(0);
		if (firstChar >= 'A' && firstChar <= 'Z') {
			char[] arr = str.toCharArray();
			arr[0] -= ('A' - 'a');
			return new String(arr);
		}
		return str;
	}
	
	public static int[] strArr2IntArr(String[] str) {
		int [] target = new int[str.length];
		for(int i = 0 ;i < str.length; i++){
			Assert.notEmpty(str[i],String.format("String[]数组转int[]数组时,第[%s]位不可以为[%s]",i,str[i]));
			target[i] = Integer.parseInt(str[i]);
		}
		return target;
	}
	
	public static float[] strArr2FloatArr(String[] str) {
		float [] target = new float[str.length];
		for(int i = 0 ;i < str.length; i++){
			Assert.notEmpty(str[i],String.format("String[]数组转float[]数组时,第[%s]位不可以为[%s]",i,str[i]));
			target[i] = Float.parseFloat(str[i]);
		}
		return target;
	}
	
	public static double[] strArr2DoubleArr(String[] str) {
		double [] target = new double[str.length];
		for(int i = 0 ;i < str.length; i++){
			Assert.notEmpty(str[i],String.format("String[]数组转double[]数组时,第[%s]位不可以为[%s]",i,str[i]));
			target[i] = Double.parseDouble(str[i]);
		}
		return target;
	}
	
	public static long[] strArr2LongArr(String[] str) {
		long [] target = new long[str.length];
		for(int i = 0 ;i < str.length; i++){
			Assert.notEmpty(str[i],String.format("String[]数组转long[]数组时,第[%s]位不可以为[%s]",i,str[i]));
			target[i] = Long.parseLong(str[i]);
		}
		return target;
	}
	
	public static Date[] strArr2DateArr(String[] str,DateFormat format) {
		Date [] target = new Date[str.length];
		for(int i = 0 ;i < str.length; i++){
			try {
				Assert.notEmpty(str[i],String.format("String[]数组转Date[]数组时,第[%s]位不可以为[%s]",i,str[i]));
				target[i] = format.parse(str[i]);
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		return target;
	}

	public static Object strArr2ShortArr(String[] str) {
		short [] target = new short[str.length];
		for(int i = 0 ;i < str.length; i++){
			Assert.notEmpty(str[i],String.format("String[]数组转short[]数组时,第[%s]位不可以为[%s]",i,str[i]));
			target[i] = Short.parseShort(str[i]);
		}
		return target;
	}

	public static boolean isJson(String json){
		if(null == json)
			return false;
		boolean bool = true;
		try{
			se.eval(String.format("var json = eval(%s);",json));
		}catch(ScriptException e){
			bool = false;
		}
		if(se.get("json").toString().equals("[object Object]"))
			bool = true;
		else
			bool = false;
		return bool;
	}

	public static String jsonFilter(String json){
		return json.replaceAll("\"\\[", "[")
				.replaceAll("\\]\"", "]").replaceAll("'", "\"").replaceAll("null", "");
	}

	public static String[] splitByUpperCase(String fields){
		return fields.split("(?=[A-Z])");
	}
	
}
